#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#define Size 10

//初始化棋盘
void InitBoard(char (*Board)[Size])
{
    for(int i = 0;i < Size;i++)
    {
        for(int j = 0;j < Size;j++)
        {
            Board[i][j] = '-';
        }
    }
}

void PrintBoard(char (*Board)[Size])
{   printf("   ");
    for(int i = 0;i < Size;i++)
    {
        printf("%3d",i + 1);
    }
    printf("\n");
    for(int i = 0;i < Size;i++)
    {
        printf("%3d",i + 1);
        for(int j = 0;j < Size;j++)
        {
            printf("%3c",Board[i][j]);
        }
        printf("\n");
 
    }
}



bool MakeMove(char (*Board)[Size],int row,int col,char player)
{
    if(row < 0 || row >= Size || col < 0 || col >= Size)
    {
        printf("非法位置，请重新输入！\n");
        return false;
    }
    if(Board[row][col] != '-')
    {
        printf("位置非空！请重新输入！\n");
        return false;
    }

    Board[row][col] = player;
    return true;
}   

//是否是合法位置
bool IsValidPlace(int row,int col)
{
    if(row < 0 || row >= Size || col < 0 || col >= Size)
    {
        return false;
    }
    return true;
}

bool CheckIsCount(char (*Board)[Size],int row,int col,char player,int num)
{
    //向量数组
    int direction[4][2] = 
    {
        {1,0},
        {1,1},
        {0,1},
        {-1,1}
    };
    //遍历4个方向，出现五个棋子则获胜
    for(int i = 0;i < 4;i++)
    {
        int count = 1;
        //下一颗棋子的位置
        int drow = row + direction[i][0];
        int dcol = col + direction[i][1];
        while(IsValidPlace(drow,dcol) && Board[drow][dcol] == player)
        {
            count++;
            if(count == num)
                return true;
            drow = drow + direction[i][0];
            dcol = dcol + direction[i][1];        
        }
        //反方向找
        drow = row - direction[i][0];
        dcol = col - direction[i][1];
        while(IsValidPlace(drow,dcol) && Board[drow][dcol] == player)
        {
            count++;
            if(count == num)
                return true;
            drow = drow - direction[i][0];
            dcol = dcol - direction[i][1];        
        }
    }
    return false;
}

bool CheckIsDrawn(char (*Board)[Size])
{
    for(int i =0;i < Size;i++)
    {
        for(int j = 0;j < Size;j++)
        {
            if(Board[i][j] == '-')
            {
                return false;
            }
        }
    }
    return true;
}

bool Prevent(char (*Board)[Size],char player,char AI)
{
    int num = 6;
    while(num-- > 3)
    {
        for(int i = 0;i < Size;i++)
        {
            for(int j = 0;j < Size;j++)
            {
                if(Board[i][j] == '-')
                {
                    Board[i][j] = player;
                    if(CheckIsCount(Board,i,j,player,num))
                    {
                        Board[i][j] = AI;
                        return true;
                    }
                    Board[i][j] = '-';
                }
            }
        }
    }
    return false;
}

bool Attack(char (*Board)[Size],char player,char AI)
{
    int num = 5;
    while(num-- > 1)
    {
        for(int i = 0;i < Size;i++)
        {
            for(int j = 0;j < Size;j++)
            {
                if(Board[i][j] == '-')
                {
                    Board[i][j] = AI;
                    if(CheckIsCount(Board,i,j,AI,num))
                    {
                        return true;
                    }
                    Board[i][j] = '-';
                }
            }
        }
    }
    return false;
}

bool AIMakeMove(char (*Board)[Size],int Playerrow,int Playercol,char player,char AI)
{
    //智能决策  策略
    //优先取胜策略
    for(int i = 0;i < Size;i++)
    {
        for(int j = 0;j < Size;j++)
        {
            if(Board[i][j] == '-')
            {
                Board[i][j] = AI;
                if(CheckIsCount(Board,i,j,AI,5))
                {
                    return true;
                }
                Board[i][j] = '-';
            }
        }
    }
    //阻止对手策略
    if(Prevent(Board,player,AI))
        return false;
    else
        if(Attack(Board,player,AI))
            return false;
    

    while(1)
    {
        int row = rand() % 10;
        int col = rand() % 10;
        if(Board[row][col] == '-')
        {
            Board[row][col] = AI;
            return false;
        }
    }
    
    // //阻止对手连成四个
    // for(int i = 0;i < Size;i++)
    // {
    //     for(int j = 0;j < Size;j++)
    //     {
    //         if(Board[i][j] == '-')
    //         {
    //             Board[i][j] = player;
    //             if(CheckIsCount(Board,i,j,player,4))
    //             {
    //                 Board[i][j] = AI;
    //                 return false;
    //             }
    //             Board[i][j] = '-';
    //         }
    //     }
    // }

    // //阻止对手连成3个
    // for(int i = 0;i < Size;i++)
    // {
    //     for(int j = 0;j < Size;j++)
    //     {
    //         if(Board[i][j] == '-')
    //         {
    //             Board[i][j] = player;
    //             if(CheckIsCount(Board,i,j,player,3))
    //             {
    //                 Board[i][j] = AI;
    //                 return false;
    //             }
    //             Board[i][j] = '-';
    //         }
    //     }
    // }

    // //阻止对手连成2个
    // for(int i = 0;i < Size;i++)
    // {
    //     for(int j = 0;j < Size;j++)
    //     {
    //         if(Board[i][j] == '-')
    //         {
    //             Board[i][j] = player;
    //             if(CheckIsCount(Board,i,j,player,2))
    //             {
    //                 Board[i][j] = AI;
    //                 return false;
    //             }
    //             Board[i][j] = '-';
    //         }
    //     }
    // }
    //随机策略
    // int diretion[4][2] = {0};
    // int count = 0;
    // for(int i = 0;i < 4;i++)
    // {

    // }

}

void Single()
{
    char Board[Size][Size] = {0};
    InitBoard(Board);
    char player = 'X';
    while(1)
    {
        PrintBoard(Board);
        int row,col;

        if(player == 'X')
        {
            printf("请|%c|选手下棋：\n",player);
            printf("请输入落棋的位置：");
            scanf("%d %d",&row,&col);
            if(MakeMove(Board,row-1,col-1,player) == false)
            {
                continue;
            }
            if(CheckIsCount(Board,row-1,col-1,player,5))
            {
            PrintBoard(Board);
            printf("恭喜|%c|选手获胜\n",player);
            break;
            }
        }
        else
        {
            printf("AI正在下棋...\n");
            if(AIMakeMove(Board,row - 1,col - 1,'X','O'))
            {
                printf("AI获胜!\n");
                PrintBoard(Board);
                break;
            }

        }

        if(CheckIsDrawn(Board))
        {
            PrintBoard(Board);
            printf("平局\n");
            break;
        }
        player = (player == 'X') ? 'O' : 'X';
    }
}

void Double()
{
    char Board[Size][Size] = {0};
    InitBoard(Board);
    char player = 'X';
    while(1)
    {
        PrintBoard(Board);
        int row,col;

        printf("请|%c|选手下棋：\n",player);
        printf("请输入落棋的位置：");
        scanf("%d %d",&row,&col);
        if(MakeMove(Board,row-1,col-1,player) == false)
        {
            continue;
        }
        
        if(CheckIsCount(Board,row-1,col-1,player,5))
        {
            PrintBoard(Board);
            printf("恭喜|%c|选手获胜\n",player);
            break;
        }
        if(CheckIsDrawn(Board))
        {
            PrintBoard(Board);
            printf("平局\n");
            break;
        }
        player = (player == 'X') ? 'O' : 'X';
    }
}

int main(int argc,char *argv[])
{
    if(argc < 2)
    {
        printf("缺少启动参数！\n");
        return 0;
    }
    char Board[Size][Size] = {0};
    InitBoard(Board);
    char player = 'X';
    if(strcmp(argv[1],"1") == 0)
    {
        printf("单机游戏！\n");
        Single();
    }
    else
    {
        printf("双人游戏！\n");
        Double(); 
        
    }
    return 0;
}